package com.runfast.waimai.web.controller;

import com.runfast.common.dao.model.RunfastCuser;
import com.runfast.common.dao.model.RunfastCuseraddress;
import com.runfast.common.dao.model.RunfastCuseraddressExample;
import com.runfast.common.dao.model.RunfastDeliverCost;
import com.runfast.common.entity.validate.group.Create;
import com.runfast.common.entity.validate.group.Update;
import com.runfast.common.service.RunfastAgentbusinessService;
import com.runfast.common.service.RunfastCuserService;
import com.runfast.common.service.RunfastCuseraddressService;
import com.runfast.common.service.RunfastDeliverCostService;
import com.runfast.common.utils.AddressUtil;
import com.runfast.common.utils.DistanceUtil;
import com.runfast.common.utils.GeoUtil;
import com.runfast.common.utils.TokenUtil;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import com.runfast.paotui.dao.model.PaotuiCost;
import com.runfast.paotui.dao.model.PaotuiCostDistance;
import com.runfast.paotui.dao.model.PaotuiCostDistanceExample;
import com.runfast.paotui.service.PaotuiCostDistanceService;
import com.runfast.paotui.service.PaotuiCostService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户地址接口
 */
@RestController("userWmAddressController")
@RequestMapping(value = "/api/user/wm/address", headers = "token")
public class AddressController {

    @Autowired
    private RunfastCuseraddressService cuseraddressService;

    @Autowired
    private RunfastAgentbusinessService agentbusinessService;

    @Autowired
    private RunfastDeliverCostService deliverCostService;

    @Autowired
    private PaotuiCostService costService;

    @Autowired
    private RunfastCuserService cuserService;

    @Autowired
    private PaotuiCostDistanceService costDistanceService;

    /**
     * 获取当前用户的收货地址列表
     *
     * @param token
     * @return
     */
    @PostMapping("/list")
    public Result<List<RunfastCuseraddress>> list(@RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);


        RunfastCuseraddressExample cuseraddressExample = new RunfastCuseraddressExample();
        cuseraddressExample.or().andCidEqualTo(userId).andDeletedIsNull();
        cuseraddressExample.or().andCidEqualTo(userId).andDeletedEqualTo(false);
        cuseraddressExample.setOrderByClause("id desc");
        List<RunfastCuseraddress> cuseraddressList = cuseraddressService.selectByExample(cuseraddressExample);

        /**
         * 地址转换
         */
        for (RunfastCuseraddress cuseraddress : cuseraddressList) {
            AddressUtil.bd09ToGcj02(cuseraddress);
        }


        return Result.ok("", cuseraddressList);
    }


    /**
     * 获取当前用户的收货地址列表
     *
     * @param token
     * @return
     */
    @PostMapping("/all")
    public Result<List<RunfastCuseraddress>> all(@RequestParam Integer agentId, @RequestParam Double fromLng, @RequestParam Double fromLat, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);
        PaotuiCost defaultCost = costService.getDefaultCost(agentId);
        if (defaultCost == null) return Result.fail(ResultCode.FAIL, "代理商未设置跑腿配送模板");

        RunfastDeliverCost defaultDeliveryTemplate = deliverCostService.getDefaultDeliveryTemplate(agentId);
        if (defaultDeliveryTemplate == null) return Result.fail(ResultCode.FAIL, "代理商未设置外卖配送模板");


        RunfastCuseraddressExample cuseraddressExample = new RunfastCuseraddressExample();
        cuseraddressExample.or().andCidEqualTo(userId).andDeletedIsNull();
        cuseraddressExample.or().andCidEqualTo(userId).andDeletedEqualTo(false);
        cuseraddressExample.setOrderByClause("id desc");
        List<RunfastCuseraddress> cuseraddressList = cuseraddressService.selectByExample(cuseraddressExample);

        /**
         * 地址转换
         */
        for (RunfastCuseraddress cuseraddress : cuseraddressList) {
            Double toLng = Double.valueOf(cuseraddress.getLongitude());
            Double toLat = Double.valueOf(cuseraddress.getLatitude());

            Integer costId = defaultCost.getId();
            Double distance = DistanceUtil.getDistanceBy(fromLng, fromLat, toLng, toLat) / 1000d;

            PaotuiCostDistanceExample costDistanceExample = new PaotuiCostDistanceExample();
            costDistanceExample.or().andCostidEqualTo(costId);
            List<PaotuiCostDistance> costDistanceList = costDistanceService.selectByExample(costDistanceExample);
            Double maxDis = 0d;
            for (PaotuiCostDistance costDistance : costDistanceList) {
                Double enddistance = costDistance.getEnddistance();
                maxDis = enddistance > maxDis ? enddistance : maxDis;
            }

            if (distance > maxDis) {
                cuseraddress.setOutRange(true);
                continue;
            }


            /**
             * 是否超出配送距离
             */


            Double maxDistance = defaultDeliveryTemplate.getMaxDistance();//以公里为单位
            String distRange = defaultDeliveryTemplate.getDistRange();

            if (maxDistance != null) {
                if (distance > maxDistance) {

                    cuseraddress.setOutRange(true);
                    continue;
                }

            } else if (StringUtils.isNotBlank(distRange)) {

                Point2D.Double piont = new Point2D.Double(toLng, toLat);

                List<Point2D.Double> psList = new ArrayList<Point2D.Double>();
                String ps[] = distRange.split("\\|");

                for (String p : ps) {
                    if (StringUtils.isNotBlank(p)) {
                        String xs[] = p.split(",");
                        if (xs.length > 1) {
                            Point2D.Double p2d = new Point2D.Double(Double.parseDouble(xs[1]), Double.parseDouble(xs[0]));
                            psList.add(p2d);
                        }
                    }

                }

                if (!GeoUtil.IsPtInPoly(piont, psList)) {
                    cuseraddress.setOutRange(true);
                    continue;
                }
            }
        }


        return Result.ok("", cuseraddressList);
    }

    /**
     * 删除当前用户所属的收货地址
     *
     * @param id
     * @param token
     * @return
     */
    @PostMapping("/delete")
    public Result delete(@RequestParam int id, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);


        /*RunfastCuseraddressExample cuseraddressExample = new RunfastCuseraddressExample();
        cuseraddressExample.or().andCidEqualTo(userId).andIdEqualTo(id);
        List<RunfastCuseraddress> cuseraddresses = cuseraddressService.selectByExample(cuseraddressExample);
        if (cuseraddresses.isEmpty()) return Result.fail(ResultCode.FAIL, "当前用户下不存在该地址");

        cuseraddressService.deleteByPrimaryKey(id);*/

        RunfastCuseraddress cuseraddress = new RunfastCuseraddress();
        cuseraddress.setId(id);
        cuseraddress.setDeleted(true);
        cuseraddressService.updateByPrimaryKeySelective(cuseraddress);
        return Result.ok("");
    }

    /**
     * 添加用户地址
     *
     * @param cuseraddress
     * @param token
     * @return
     */
    @PostMapping("/add")
    public Result add(@Validated(Create.class) @ModelAttribute RunfastCuseraddress cuseraddress, BindingResult bindingResult, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        FieldError fieldError = bindingResult.getFieldError();
        if (fieldError != null)
            return Result.fail(ResultCode.PARAMETER_ERROR, fieldError.getField() + " " + fieldError.getDefaultMessage());

        cuseraddress.setId(null);
        RunfastCuser cuser = cuserService.selectByPrimaryKey(userId);

        cuseraddress.setCid(userId);
        cuseraddress.setCname(cuser.getName());
        cuseraddress.setMobile(cuser.getMobile());
        cuseraddress.setCreateTime(new Date());

        AddressUtil.gcj02ToBd09(cuseraddress);
        int i = cuseraddressService.insertSelective(cuseraddress);

        return Result.ok("");
    }

    /**
     * 修改用户地址
     *
     * @param cuseraddress
     * @param token
     * @return
     */
    @PostMapping("/update")
    public Result update(@Validated(Update.class) @ModelAttribute RunfastCuseraddress cuseraddress, BindingResult bindingResult, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);
        FieldError fieldError = bindingResult.getFieldError();
        if (fieldError != null)
            return Result.fail(ResultCode.PARAMETER_ERROR, fieldError.getField() + " " + fieldError.getDefaultMessage());


        AddressUtil.gcj02ToBd09(cuseraddress);
        cuseraddressService.updateByPrimaryKeySelective(cuseraddress);
        return Result.ok("");
    }


    /**
     * 获取地址详情
     * @param addressId
     * @param token
     * @return
     */
    @PostMapping("/detail")
    public Result<RunfastCuseraddress> detail(@RequestParam Integer addressId, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);


        RunfastCuseraddressExample cuseraddressExample = new RunfastCuseraddressExample();
        cuseraddressExample.or().andIdEqualTo(addressId).andCidEqualTo(userId);
        List<RunfastCuseraddress> cuseraddressList = cuseraddressService.selectByExample(cuseraddressExample);

        if(cuseraddressList.isEmpty()) return Result.fail(ResultCode.FAIL, "当前用户下不存在该地址");
        RunfastCuseraddress cuseraddress = cuseraddressList.get(0);



        return Result.ok("", cuseraddress);
    }
}
